package com.tbit.uqbike.quartz;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tbit.uqbike.constant.RedisConstant;
import com.tbit.uqbike.object.pojo.*;
import com.tbit.uqbike.service.business.VoiceLogServiceImpl;
import com.tbit.uqbike.webmanager.dao.core.MachineDao;
import com.tbit.uqbike.webmanager.dao.core.UpgradeDao;
import com.tbit.uqbike.webmanager.dao.core.VoiceConfigDao;
import com.tbit.uqbike.webmanager.util.StringUtil;
import com.tbit.uqbike.webmanager.util.redis.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 解析车辆自定义语音升级详细
 *
 * @author <a href="mailto:liu.haoxiang@tbit.com.cn">BUGXiang</a>
 * @version 1.0
 * @since 2024/3/26
 */
@Component
@Slf4j
public class VoiceQuartz {

    @Resource
    private RedisUtil redisUtil;
    @Resource
    private VoiceConfigDao voiceConfigDao;
    @Resource
    private MachineDao machineDao;
    @Resource
    private VoiceLogServiceImpl voiceLogService;
    @Resource
    private UpgradeDao upgradeDao;
    @Resource
    @Qualifier("redisTemplate")
    private RedisTemplate<String, String> redisTemplate;

    /**
     * 获取配置文件最新版本
     */
    @Scheduled(fixedRate = 60000)
    public void initVoiceVersion() {
        QueryWrapper<VoiceConfig> queryWrapper = new QueryWrapper<>();
        List<VoiceConfig> voiceConfigs = voiceConfigDao.selectList(queryWrapper);
        if (voiceConfigs.isEmpty()) {
            log.warn("当前版本号为空");
            return;
        }
        Map<String, String> collect = voiceConfigs.stream().collect(Collectors.toMap(voiceConfig -> String.valueOf(voiceConfig.getAccountId()), VoiceConfig::getVersion));
        redisTemplate.opsForHash().putAll(RedisConstant.VOICE_CONFIG_KEY, collect);
        redisTemplate.expire(RedisConstant.VOICE_CONFIG_KEY, 30, TimeUnit.SECONDS);
    }

    /**
     * 校验
     * @param respMsg mq消息
     * @param terResInfoList 消息列表
     * @param machineNoList 设备列表
     */
    private void getTerResInfo(String respMsg, List<TerResInfo> terResInfoList, List<String> machineNoList) {
        TerResInfo terResInfo = JSON.parseObject(respMsg, TerResInfo.class);
        if (Objects.isNull(terResInfo)) {
            log.error("解析语音回调消息失败:{}", respMsg);
            return;
        }
        machineNoList.add(terResInfo.getMno());
        terResInfoList.add(terResInfo);
    }

    @Scheduled(cron = "0/30 * * * * ?")
    public void handleMessage() {
        String s;
        while ((s = redisUtil.lLeftPop(RedisConstant.VOICE_LPUSH_KEY)) != null) {
            //lpop移出1000个数据进行批量操作
            List<TerResInfo> terResInfoList = new ArrayList<>();
            List<String> machineNoList = new ArrayList<>();
            getTerResInfo(s, terResInfoList, machineNoList);
            for (int i = 0; i < 1000; ++i) {
                getTerResInfo(redisUtil.lLeftPop(RedisConstant.VOICE_LPUSH_KEY), terResInfoList, machineNoList);
            }
            //查询这1000个设备编号的区域id
            Map<String, Object> params = new HashMap<String, Object>();
            params.put("machineNOs", StringUtil.getArrayListString(machineNoList));
            List<Machine> machineList = machineDao.getByMachineNOs(params);
            Map<String, Integer> collect = machineList.stream().collect(Collectors.toMap(Machine::getMachineNO, Machine::getAccountId));
            Set<Integer> accountIdSet = machineList.stream().map(Machine::getAccountId).collect(Collectors.toSet());
            //查询版本号
            Map<Integer, String> versionMap = voiceConfigDao.selectByAccountId(accountIdSet);
            //循环构建新增的数据
            List<VoiceLog> logs = new ArrayList<>();
            List<UpgradeDetail> machines = new ArrayList<>();
            for (TerResInfo terResInfo : terResInfoList) {
                //根据设备编号获取区域id 根据区域id获取版本号
                Integer accountId = collect.get(terResInfo.getMno());
                if (Objects.isNull(accountId)) {
                    log.info("设备不存在，设备编号:{}", terResInfo.getMno());
                    continue;
                }
                String version = versionMap.get(accountId);
                if (Objects.isNull(version)) {
                    log.info("该区域配置文件版本为空,区域id:{}", accountId);
                    continue;
                }
                //网关回调的版本号与当前版本号不一致直接抛弃
                if (!version.equals(terResInfo.getResVersion().toString())) {
                    continue;
                }
                //构建新增对象
                VoiceLog voiceLog = new VoiceLog();
                voiceLog.setMachineNo(terResInfo.getMno())
                        .setVersion(version)
                        .setResStatus(terResInfo.getResStatus())
                        .setCreateTime(new Date());
                logs.add(voiceLog);
                //构建修改对象
                UpgradeDetail upgradeDetail = new UpgradeDetail();
                upgradeDetail.setMachineNo(terResInfo.getMno());
                if (!terResInfo.getResStatus().contains("0")){
                    //升级成功
                    upgradeDetail.setType("1");
                }else if (!terResInfo.getResStatus().contains("1")){
                    //升级失败
                    upgradeDetail.setType("3");
                }else {
                    //部分成功
                    upgradeDetail.setType("2");
                }
                machines.add(upgradeDetail);
            }
            //批量新增
            voiceLogService.saveBatch(logs);
            //根据结果批量修改车辆的升级状态
            upgradeDao.batchUpdate(machines);
        }


    }

}
